package cn.com.cetccst.appstore.ui.activity;

import android.annotation.TargetApi;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;
import android.webkit.DownloadListener;
import android.webkit.GeolocationPermissions;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

/**
 * 网页浏览父类，提供基础网页浏览功能，不可直接使用
 */
public abstract class BaseWebActivity extends AppCompatActivity {
    private static final int FILECHOOSER_RESULTCODE_FOR_ANDROID = 1001;
    protected static final String WEB_ERROR_PATH = "file:///android_asset/web_error/web_error.html";
    protected static final String WEB_SERVER_ERROR_PATH = "file:///android_asset/web_error/web_server_error.html";
    protected static final String WEB_OPEN_BY_BROWSER_PATH = "file:///android_asset/web_error/web_open_by_browser.html";
    public static final String URL_EXTRA = "html_uri";
    public static final String DEFINED_TILE = "define_title";
    public static final String IS_SHOW_TITLEBAR = "is_show_title_bar";
    public static final String IS_ALLOW_CHOOSE_FILE = "is_allow_choose_file";//是否允许网页从本地选择文件. 目前只放开图片选择
    public static final String IS_ALLOW_DOWNLOAD_FILE = "is_allow_down_file";//是否允许网页下载文件
    public static final String IS_ALLOW_GET_LOCATION = "is_allow_get_location";//是否允许网页获取定位
    /**
     * Show progress when load url
     */
    protected ProgressBar mProgressView = null;
    protected WebView mWebView;
    protected View mRootView;
    protected String mShowDefinedTitleStr = "";
    protected String mUrlHtmlString = "about:blank";
    protected Toolbar mTopToolbar;
    private boolean isAllowChooseFile = true;
    private boolean isAllowDownloadFile = true;
    private boolean isAllowGetLocation = false;
    protected boolean isCanOpenByBrowser = false;
    private ValueCallback<Uri[]> mUploadMessage;
    private WebChromeClient mWebChromeClient = null;
    private WebViewClient mWebViewClient = null;
    private DownloadListener mWebDownloadListener = null;

    protected void getIntentData() {
        Intent intent = getIntent();
        mShowDefinedTitleStr = intent.getStringExtra(DEFINED_TILE);
        if (!TextUtils.isEmpty(intent.getStringExtra(URL_EXTRA))) {
            mUrlHtmlString = intent.getStringExtra(URL_EXTRA);
        }
        isAllowChooseFile = intent.getBooleanExtra(IS_ALLOW_CHOOSE_FILE, true);
        isAllowDownloadFile = intent.getBooleanExtra(IS_ALLOW_DOWNLOAD_FILE, true);
        isAllowGetLocation = intent.getBooleanExtra(IS_ALLOW_GET_LOCATION, false);
    }

    protected void setWebViewClient(WebViewClient webViewClient) {
        mWebViewClient = webViewClient;
    }

    protected void setWebChromeClient(WebChromeClient webChromeClient) {
        mWebChromeClient = webChromeClient;
    }

    protected void setWebDownloadListener(DownloadListener webDownloadListener) {
        mWebDownloadListener = webDownloadListener;
    }

    protected void initWebView() {
        if (mWebChromeClient == null) {
            mWebChromeClient = new CXBaseWebChromeClient();
        }
        mWebView.setWebChromeClient(mWebChromeClient); // 设置setWebChromeClient对象
        if (mWebViewClient == null) {
            mWebViewClient = new CXBaseWebViewClient();
        }
        mWebView.setWebViewClient(mWebViewClient);
        //设置这个listener后，如果页面存在链接是下载文件会响应启动相关下载组件
        if (mWebDownloadListener == null) {
            mWebDownloadListener = new CXBaseWebDownloadListener();
        }
        mWebView.setDownloadListener(mWebDownloadListener);
        initWebSetting();
        webLoadWhenInit();
    }

    protected void webLoadWhenInit() {
        loadUrl(mUrlHtmlString);
    }

    protected void initWebSetting() {
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setUseWideViewPort(true);//设置此属性，可任意比例缩放
        webSettings.setLoadWithOverviewMode(true);
//        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setBlockNetworkImage(false);
//        webSettings.setSavePassword(true);//add
//        webSettings.setAllowFileAccess(true);//add
//        webSettings.setAppCacheEnabled(true);//add
//        webSettings.setDatabaseEnabled(true);//add
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//LOAD_NO_CACHE LOAD_DEFAULT
        webSettings.setAllowFileAccessFromFileURLs(false);
        webSettings.setDomStorageEnabled(true);
        webSettings.setBuiltInZoomControls(true);
        webSettings.setDisplayZoomControls(false);
        webSettings.setSupportZoom(true);
        //自适应屏幕
        webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);//NARROW_COLUMNS
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }

    }

    /**
     * 一些网页是存模板生成，没有JS代码，所以token认证放在头
     *
     * @param url
     */
    protected void loadUrl(String url) {
        mWebView.loadUrl(url);
    }

    protected void webPageTitleLoaded(String loadedTitle) {

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mWebView.removeAllViews();
        mWebView.clearHistory();
        mWebView.clearFormData();
        mWebView.clearCache(true);
        mWebView.destroy();
    }


    @Override
    public void onPause() {//继承自Activity
        super.onPause();
        mWebView.onPause();
    }

    @Override
    public void onResume() {//继承自Activity
        super.onResume();
        mWebView.onResume();
    }

    /**
     * 网页中存在链接，可以点击下载文件的功能
     */
    protected class CXBaseWebDownloadListener implements DownloadListener {
        @Override
        public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
            if (isAllowDownloadFile) {
                try {
                    Uri uri = Uri.parse(url);
                    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                    startActivity(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                mWebView.stopLoading();
                mWebView.loadUrl(isCanOpenByBrowser ? WEB_OPEN_BY_BROWSER_PATH : WEB_SERVER_ERROR_PATH);
            }
        }
    }

    /**
     * Listener for load states
     */
    protected class CXBaseWebViewClient extends WebViewClient {
        @Override
        public void onPageFinished(WebView view, String url) {
            try {
                view.setLayerType(View.LAYER_TYPE_NONE, null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            super.onPageFinished(view, url);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            try {
                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            super.onPageStarted(view, url, favicon);

        }

        //加载https时候，需要加入 下面代码
        @Override
        public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
//            final BaseAlertDialog baseAlertDialog = new BaseAlertDialog();
//            baseAlertDialog.initDialog(getString(R.string.webview_ssl_error_hint));
//            baseAlertDialog.setNegativeBtnString(getString(R.string.common_cancel));
//            baseAlertDialog.setPositiveBtnString(getString(R.string.common_sure));
//            baseAlertDialog.setCancelAble(true);
//            baseAlertDialog.setListener(new CXDialogInterface.DialogButtonClickListener() {
//                @Override
//                public void dialogStatusChanged(int flag) {
//                    try {
//                        // 双屏手机会触发崩溃
//                        baseAlertDialog.dismiss();
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                    if (flag == CXDialogInterface.DIALOG_CLICK_POSITIVE_BTN) {//确定
//                        //接受所有证书
//                        handler.proceed();
//                    } else if (flag == CXDialogInterface.DIALOG_CLICK_NEGATIVE_BTN) {
//                        handler.cancel();//默认处理方式
//                        mWebView.stopLoading();
//                        String errorDes = getString(R.string.webview_ssl_error_message);
//                        String errorTitle = getString(R.string.webview_ssl_error_title);
//                        mWebView.loadUrl(WEB_SERVER_ERROR_PATH + "?errorMsg=" + errorDes + "&title=" + errorTitle);
//                    }
//                }
//            });
//            baseAlertDialog.show(getSupportFragmentManager(), "ssl_error");
//
//
//            if (Release.isNeedIgnoreCertificate()) {
                handler.proceed();  //接受所有证书
//            } else {
//                super.onReceivedSslError(view, handler, error);
//                handler.cancel();//默认处理方式
//                mWebView.stopLoading();
//                String errorDes = "";
//                try {
//                    errorDes = URLEncoder.encode("安全警告：服务器证书域名不匹配", "UTF-8");
//                } catch (Exception e) {
//                }
//                mWebView.loadUrl(isCanOpenByBrowser ? WEB_OPEN_BY_BROWSER_PATH : WEB_SERVER_ERROR_PATH + "?errorMsg=" + errorDes);
//            }
        }

        @Override
        @TargetApi(Build.VERSION_CODES.M)
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);
            if (request.isForMainFrame()) {
                if (error.getErrorCode() == WebViewClient.ERROR_UNSUPPORTED_SCHEME) {
                    view.stopLoading();
                    view.loadUrl(isCanOpenByBrowser ? WEB_OPEN_BY_BROWSER_PATH : WEB_SERVER_ERROR_PATH);
                } else if (error.getErrorCode() == WebViewClient.ERROR_HOST_LOOKUP || error.getErrorCode() == WebViewClient.ERROR_BAD_URL || error.getErrorCode() == WebViewClient.ERROR_CONNECT || error.getErrorCode() == WebViewClient.ERROR_TIMEOUT) {
                    view.stopLoading();
                    view.loadUrl(WEB_ERROR_PATH);
                }
            }
        }

        // 旧版本，会在新版本中也可能被调用，所以加上一个判断，防止重复显示
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                return;
            }
            if (errorCode == WebViewClient.ERROR_UNSUPPORTED_SCHEME) {
                view.stopLoading();
                view.loadUrl(isCanOpenByBrowser ? WEB_OPEN_BY_BROWSER_PATH : WEB_SERVER_ERROR_PATH);
            }
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            String url = request.getUrl().toString();
            if (url.startsWith("http") || url.startsWith("https") || url.startsWith("ftp") || url.startsWith("jsbridge")) { // jsbridge 是腾讯共享文档类型
                return false;//false 是系统处理
            } else if (url.startsWith("tel")) { //判断用户单击的是那个超连接
                try {
                    String mobile = url.substring(url.lastIndexOf("/") + 1);
                    mobile = mobile.substring(mobile.lastIndexOf(":") + 1);
                    handleTelLink(mobile);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return true;
            } else if (url.startsWith("weixin://") || url.startsWith("alipays://")) { //H5支付直接跳转微信或支付宝
                try {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse(url));
                    startActivity(intent);
                    return true;
                } catch (Exception exception) {
                    exception.printStackTrace();
                    view.stopLoading();
                    view.loadUrl(isCanOpenByBrowser ? WEB_OPEN_BY_BROWSER_PATH : WEB_SERVER_ERROR_PATH);
                }
            } else if (url.startsWith("wemeet://")) { //腾讯会议链接点击加入会议时直接跳转应用
                try {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse(url));
                    startActivity(intent);
                    return true;
                } catch (Exception exception) {
                    exception.printStackTrace();
                    view.stopLoading();
                    view.loadUrl(isCanOpenByBrowser ? WEB_OPEN_BY_BROWSER_PATH : WEB_SERVER_ERROR_PATH);
                }
            } else {
                //目前除了微信、支付宝支付外，暂不开启启动原生应用，通知到浏览器打开
                view.stopLoading();
                view.loadUrl(isCanOpenByBrowser ? WEB_OPEN_BY_BROWSER_PATH : WEB_SERVER_ERROR_PATH);
            }
            return false;//false 是系统处理
        }

        @Nullable
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            return super.shouldInterceptRequest(view, request);
        }
    }

    protected class CXBaseWebChromeClient extends WebChromeClient {
        @Override
        public void onReceivedTitle(WebView view, String title) {//显示标题
            super.onReceivedTitle(view, title);
            if (!mWebView.getUrl().equals(WEB_OPEN_BY_BROWSER_PATH) && !mWebView.getUrl().equals(WEB_ERROR_PATH) && !mWebView.getUrl().startsWith(WEB_SERVER_ERROR_PATH)) {
                if (!TextUtils.isEmpty(mShowDefinedTitleStr)) {
                    mTopToolbar.setTitle(mShowDefinedTitleStr);
                } else {
                    mTopToolbar.setTitle(title);
                }
                webPageTitleLoaded(title);
            }

        }

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress == 100) {
                mProgressView.setVisibility(View.GONE);
            } else {
                if (mProgressView.getVisibility() == View.GONE) {
                    mProgressView.setVisibility(View.VISIBLE);
                }
                mProgressView.setProgress(newProgress);
            }

            super.onProgressChanged(view, newProgress);
        }


        @Override
        public boolean onShowFileChooser(WebView mWebView,
                                         ValueCallback<Uri[]> filePathCallback,
                                         FileChooserParams fileChooserParams) {
            if (isAllowChooseFile) {
                if (mUploadMessage != null) {
                    mUploadMessage.onReceiveValue(null);
                    mUploadMessage = null;
                }
                mUploadMessage = filePathCallback;
                Intent intent = fileChooserParams.createIntent();
                try {
                    startActivityForResult(intent, FILECHOOSER_RESULTCODE_FOR_ANDROID);
                } catch (ActivityNotFoundException e) {
                    mUploadMessage = null;
                    return false;
                }
            }
            return true;
        }

        @Override
        public void onGeolocationPermissionsShowPrompt(final String origin, final GeolocationPermissions.Callback callback) {
            if (isAllowGetLocation) {
//                callback.invoke(origin, checkIsHasPermission(CXPermissionUtil.CODE_ACCESS_FINE_LOCATION), false);
            }
        }
    }

    private void handleTelLink(final String phoneNum) {
//        final String[] items = new String[]{getString(R.string.web_view_copy_num), getString(R.string.web_view_call_num)};
//        final MenuListPopupWindow window = new MenuListPopupWindow(this, new MenuListPopupWindow.PopWindowEventListener() {
//            @Override
//            public void onPopItemClick(String itemString, int position, Object data) {
//                if (position == 0) {
//                    copyNum(phoneNum);
//                } else if (position == 1) {
//                    call(phoneNum);
//                }
//            }
//
//            @Override
//            public void onPopDismiss(String tag) {
//
//            }
//        }, "", items, null);
//        window.setWidthAndHeight(400, 200, WindowManager.LayoutParams.WRAP_CONTENT);
//        window.setBackground(R.drawable.popup_menu_background);
//        window.setBackgroundAlpha(this.getWindow(), 0.55f);
//        window.setAnimationStyle(R.style.bottom_popwin_anim_style);
//        window.resetItemTextGravity(Gravity.CENTER);
//        window.showAtLocation(mRootView, Gravity.CENTER, 0, 0);
    }


    private void call(String phoneNum) {
        try {
            Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNum));
            dialIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(dialIntent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void copyNum(String phoneNum) {
        ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clip = ClipData.newPlainText("phone", phoneNum);
        clipboard.setPrimaryClip(clip);
    }

}